<?php

namespace App\Modules\Apicrzs\Services;

use App\Modules\Admin\Entities\Member\UserExtractModel;
use App\Modules\Admin\Entities\Water\WaterDeviceModel;
use App\Modules\Admin\Entities\Water\WaterWithUserModel;
use App\Modules\Apicrzs\Entities\UserScoreModel;
use App\Modules\Apicrzs\Entities\UsersWithApparatuses;
use App\Traits\CryptAES;
use Carbon\Carbon;
use Illuminate\Support\Arr;

class UserScoreService extends BaseServices
{

    public function __construct(UserScoreModel $model)
    {
        $token =  \request()->header('token');
        $user_info = CryptAES::decryptToken($token,'user_grzq');
//
        $this->user_id = $user_info['data']['user_id']??"";
        $this->model = $model;
        $this->waterDeviceModel = new WaterDeviceModel();
    }
    public function lists(array $params): array
    {
        $user_id = $this->user_id;
        $type = $params['type'];
        $time = $params['time'].'-01';
        [$start_time,$end_time] =  $this->paramsWhereTime(['type'=>$type,'time'=>$time]);

        $result = $this->model->getUserScoreDays(['user_id'=>$user_id,'start_time'=>$start_time,'end_time'=>$end_time]);

        foreach ($result as &$item){
            $item['value'] = (float)sprintf('%.3f', $item['value']);
        }
        return $result;
    }
    /**
     * 当前积分详情（提现只能当月以前，所以全都是flag=0的）
     * @param $uid
     * @return array
     */
    public function statistics($params): array
    {
        //昨日积分
        [$start_time,$end_time] =  $this->paramsWhereTime(['type'=>2,'time'=>time()]);
        $orm = UserScoreModel::where('user_id', $this->user_id)->where('flag',UserScoreModel::GAIN)->where('is_delete', 0);
        $yesterdayOrm = clone $orm; // 克隆对象避免冲突

        $yesterday = $yesterdayOrm->where("gift_time",">=",$start_time)
            ->where("gift_time","<=",$end_time)->sum('score');

        //累计获取
        $all = $orm->sum('score');
        [$startOfMonth,$endOfMonth] = getThisMonth(date("Y-m"));

        // 本月$gift_time
        $monthOrm = clone $orm; // 克隆对象避免冲突
        $month = $monthOrm->where("gift_time",">=",strtotime($startOfMonth))
            ->where("gift_time","<=",strtotime($endOfMonth))
            ->sum('score');

        //积分本为3位小数，罗总2024年8月27日 15:11 确定显示整数（未考虑会出现负数积分场景）
        return [
            'yesterday' => floor($yesterday),//昨天
            'all' => floor($all),//全部
            'month' => floor($month),//本月
        ];
    }

    public function getCountSum(){
        $result = $this->model->where(['user_id'=>$this->user_id,'is_delete' => 0])->sum('score');
        return ['sum'=>$result];
    }
    // 昨天积分
    public function getUserApparatusScoreList(){
        $user_id = $this->user_id;
        $waterList =  WaterWithUserModel::getInstance()->getUserWithWaterByIds($user_id);
        $waterIds = array_keys($waterList);

        $model = $this->waterDeviceModel->whereIn('water_id',$waterIds)->where(['status'=>1,'is_delete' => 0])
            ->select(['water_id','water_title','code','type']);

        $result = $model->paginate($this->getLimit($params['limit'] ?? 10));

        $userScore = $this->model->getUserScoreLastDays(['user_id'=>$user_id]);
        $userScoreCount = $this->model->getUserScoreSumCount(['user_id'=>$user_id]);

        $lists_data=[];
        foreach ($result->items() as $item) {
            $lists_data[] = [
                'id' => $item['water_id'],
                'title' => $item['water_title'],
                'code' => $item['code'],
                'type' => $item['type'],
                'address' => $item['address'],
                'score_sum' => $userScore[$item['water_id']]??0,
                'score_count' =>  $userScoreCount[$item['water_id']]??0,
            ];
        }
        return $lists_data;
        return  [
            'current_page' => $result->currentPage(),//当前
            'per_page' => $result->perPage(),//每页 10 条
            'count_page' => $result->lastPage(),//
            'total' => $result->total(), // 总数
            'data' => $lists_data,
        ];
    }

    /**
     * 累计积分
     * @return void
     */
    public function getAccumulateScoreList($params){
        $user_id = $this->user_id;
        $waterList =  WaterWithUserModel::getInstance()->getUserWithWaterByIds($user_id);
        $waterIds = array_keys($waterList);
        $apparatus_list = $this->waterDeviceModel->whereIn('water_id',$waterIds)->where(['status'=>1,'is_delete' => 0])
            ->orderBy('signed_at', 'asc')
            ->get(['water_id','water_title as title','signed_at'])->toArray();

        // 获取当前年份和月份
        $months_signed_at = array_column($apparatus_list,'signed_at');
        $currentYearMonth = date('Y-m');
        $months_ranges = get_month_range($months_signed_at[0],$currentYearMonth);

        $mergedData = [];
        $groupedData = [];
        foreach ($apparatus_list as $item) {
            $yearMonth = date('Y-m', strtotime($item['signed_at']));
            foreach ($months_ranges as $month){
                $_month  = date('Y-m',strtotime($month));
                if (!isset($groupedData[$_month])) {
                    $groupedData[$_month] = [];
                }
                $groupedData[$_month][] = $item;
            }
        }

        $months = array_keys($groupedData);

        // 合并小于当前月的数据，并以每月递增的方式保留这些数据
        $tempData = [];
        foreach ($groupedData as $yearMonth => $monthData) {
            // 如果当前处理的月份小于当前月份，则合并到tempData中
            if ($yearMonth < $currentYearMonth) {
                $tempData = array_merge($tempData, $monthData);
                $mergedData[$yearMonth] = array_merge($tempData, $monthData);
            } else {
                // 否则，将之前合并的数据与当前月份的数据合并，并存储到mergedData中
                // 同时重置tempData为当前月份的数据，以便后续月份的处理
                $mergedData[$yearMonth] = array_merge($tempData, $monthData);
                $tempData = $monthData; // 重置tempData为当前月份的数据（用于后续可能的合并）
                // 注意：由于我们要求“1月数据合并到2月，1月2月的数据合并到3月中，以此类推”，
                // 因此在这里我们不需要再将tempData重置为空数组，而是保留当前月份的数据，
                // 以便与下一个月份的数据进行合并。但在本示例中，由于我们按月份遍历数据，
                // 所以每个月份的数据只会被处理一次，并合并到相应的结果中。
                // 如果数据不是按月份顺序排列的，或者需要更复杂的合并逻辑，请根据实际情况进行调整。
            }
        }
        $month_apparatus_score=[];
        foreach ($months as $month){
            $month_apparatus = $this->model->getUserAccumulateScore(['user_id'=>$user_id,'month'=>$month]);
            $apparatus_value =  array_column($month_apparatus,'value','water_id');
            $month_apparatus_score[$month] = $apparatus_value;
        }

        krsort($groupedData);
        $resultMergedData=[];
        foreach ($groupedData as $month => $items) {
            $score_count =0;
            foreach ($items as $key=>&$item){
                $score = $month_apparatus_score[$month][$item['water_id']]??0;
                $item['score'] = $score;
                $score_count+=$score;
            }
            $resultMergedData[] = ['count'=>count($items),'score_count'=>$score_count,'date' => $month, 'data' => $items];
        }


        return $resultMergedData;
    }
    public function getUserApparatusMonthScore($apparatus_id,$user_id,$gift_time){

        $start_time = Carbon::parse($gift_time)->startOfMonth()->toDateString();
        $end_time = Carbon::parse($gift_time)->endOfMonth()->toDateString();
        $start_time = strtotime($start_time . ' 00:00:00');
        $end_time = strtotime($end_time . ' 23:59:59');
        $sum_score = $this->model->where(['water_id'=>$apparatus_id,'user_id'=>$user_id,'is_delete' => 0])
            ->whereBetween('gift_time', [$start_time, $end_time])
            ->sum("score");
        return $sum_score;
    }
    /** 已提现
     * @param $uid
     * @return array
     */
    public function usableBalance(): array
    {
        $transactionModel = UserExtractModel::getInstance();
        //仅能提现当月以前的
        [$startOfMonth,$endOfMonth] = getThisMonth(date("Y-m",strtotime("-1 month")));
        $month_count_list = $transactionModel->where(['user_id'=>$this->user_id,'month'=>date('Y-m-01',strtotime($startOfMonth))])->get()->toArray();
//        exit(json_encode($month_count));

        $extract_price =0;
        if (count($month_count_list)!=0){
            $take =0;
            foreach ($month_count_list as $item){
//                if ($item['status']){
                    $extract_price+=$item['extract_price'];
//                }
            }

        }
        $take = UserScoreModel::getInstance()->where(['user_id'=>$this->user_id])->whereBetween('gift_time', [strtotime($startOfMonth), strtotime($endOfMonth)])->sum('score');


        return ['score'=>(float)sprintf('%.3f',$take-$extract_price)];//注意：已提现的为负数，所以相加，别改成相减，改了出bug请自抽。
    }

    /**
     *  提现
     * @param $id
     * @param $uid
     * @param $score
     * @return bool
     */
    public function take($params): bool
    {
        $user_bank_id= $params['user_bank_id']??"";
        $uid= $this->user_id;
        $score= $params['score']??"";
        if(!$user_bank_id) {
            $this->error='请选择银行卡!';
            return false;
        }
        if($score < 1) {
            $this->error='申请额度最低为1积分!';
            return false;
        }
        $scoreInfo = $this->usableBalance($this->user_id);
        $maxScore = Arr::get($scoreInfo,'score');
        if($score>$maxScore) {
            $this->error='超出最大额度!';
            return false;
        }
        $data = [
            'user_bank_id' => $user_bank_id,
            'user_id' => $this->user_id,
            'score' => -$score,//注意：提现是负数，别改成正数，改了出bug请自抽。
            'state' => 1,
            'flag' => UserScoreModel::TAKE,
        ];
        $bool = UserScoreModel::where('user_id', $this->user_id)->create($data);
        if(!$bool){
            $this->error='申请出错，请重试！!';
            return false;
        }
        return true;
    }


    // 时间条件
    protected function paramsWhereTime($params)
    {
        $type = $params['type'];
        $specificDate = $params['time']??"";
        switch ($type){
            case 1:
                // 如果你想获取特定日期的月份的第一天和最后一天
                $start_time = Carbon::parse($specificDate)->startOfMonth()->toDateString();
                $end_time = Carbon::parse($specificDate)->endOfMonth()->toDateString();
                $inputData['start_time'] = strtotime($start_time . ' 00:00:00');
                $inputData['end_time'] = strtotime($end_time . ' 23:59:59');
                break;
            case 2:
                // 昨天
                $day_time = date("Y-m-d", strtotime("-1 day"));
                $inputData['start_time'] = strtotime($day_time . ' 00:00:00');
                $inputData['end_time'] = strtotime($day_time . ' 23:59:59');
                break;
            case 3:
                // 获取年份第一天
                $start_time = Carbon::parse($specificDate)->startOfYear()->toDateString();
                $end_time = Carbon::parse($specificDate)->endOfYear()->toDateString();
                $inputData['start_time'] = strtotime($start_time . ' 00:00:00');
                $inputData['end_time'] = strtotime($end_time . ' 23:59:59');
                break;
            default:
                $start_time = Carbon::parse($params['start_time']??'')->startOfDay()->toDateString();
                $end_time = Carbon::parse($params['end_time']??'')->startOfDay()->toDateString();
                $inputData['start_time'] = $start_time . ' 00:00:00';
                $inputData['end_time'] = $end_time . ' 23:59:59';
                break;
        }

        return [$inputData['start_time'],$inputData['end_time']];
    }

}
